package control;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.lang.String;
import java.net.Authenticator;
import java.net.HttpURLConnection;
import java.net.InetAddress;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.net.UnknownHostException;
import java.util.Vector;
import org.apache.soap.Constants;
import org.apache.soap.SOAPException;
import org.apache.soap.encoding.SOAPMappingRegistry;
import org.apache.soap.encoding.soapenc.FloatDeserializer;
import org.apache.soap.rpc.Call;
import org.apache.soap.rpc.Parameter; 
import org.apache.soap.util.xml.QName;

import model.Patente;


/**
 * UrlReader
 * @author Adriano de Albuquerque Batista
 * @author Alfeu Buriti
 * @author Pablo Diego Alencar
 * @author Yuri Cariry Cabral de Melo
 *
 */
public class UrlReader {

	// constantes
	final   String INPI_IP		 = "172.16";
	final   String INPI_HOST 	 = "proxy.inpi.gov.br";
	final   String INPI_PORT 	 = "8080";
	final	String proxyUser	 = "abatista";
	final   String proxyPassword = new InFile().readFile("proxy.txt");

	// variaveis globais
	private String title 		= new String();// empty initialization
	private String absTract 	= new String();
	private String claims 		= new String();
	private String description 	= new String();


	/**
	 * Construtor vazio UrlReader
	 */
	public UrlReader() {
	}


	/**
	 * configProxy
	 * faz o configProxy detectar a necessidade de um proxy ou nao
	 * encriptar o proxy connection.
	 * Get Hostname.
	 */
	public void configProxy() {
		System.out.println("Inicio do UrlReader -> configProxy ");

		String ip = null;
		try {
			InetAddress localhost = InetAddress.getLocalHost();
			ip = localhost.getHostAddress();
			// hostname=localhost.getHostName();
			System.out.println("ip local eh " + ip);
		} catch (UnknownHostException ex) {
			if (ip == null) {
				System.err.println("Sem ip");
				System.err.println(ex.toString());
				System.exit(1);
			}
		}
		// Configurar proxy somente se estivermos no INPI
		if (ip.contains(INPI_IP)) {
			// System.setProperty("http.proxySet", "true");
			System.setProperty("http.proxyHost", INPI_HOST);
			System.setProperty("http.proxyPort", INPI_PORT);
			// System.setProperty("http.proxyType", "4");			

			Authenticator.setDefault(new SimpleAuthenticator(proxyUser,
					proxyPassword));
		}
		System.out.println("Fim do UrlReader -> configProxy ");
	}



	/**
	 * fetchUrlDocument
	 * filter http directives
	 * @param urlLink urlLink
	 */
	private void fetchUrlDocument(String urlLink) {
		System.out.println("Inicio do UrlReader -> fetchUrlDocument ");

		try {
			URL url = new URL(urlLink);
			URLConnection uc = url.openConnection();
			BufferedReader in = new BufferedReader(
					new InputStreamReader(uc.getInputStream()));
			// filter http directives
			patReader(in);
			in.close();
		} catch (MalformedURLException e) {
			System.err.println(e.toString());
			System.exit(1);
		} catch (IOException e) {
			System.err.println(e);
			System.exit(1);
		}
		System.out.println("Fim do UrlReader -> fetchUrlDocument ");
	}



	/**
	 * ptoReader 
	 * @param urlLink
	 * @return patente
	 */
	public Patente ptoReader(String urlLink) {
		System.out.println("Inicio do UrlReader -> ptoReader ");

		// Configure proxy ...
		configProxy();
		// download URL document...
		fetchUrlDocument(urlLink);
		Patente patente = new Patente(title, absTract, description, claims);

		System.out.println("Fim do UrlReader -> ptoReader ");
		return patente;
	}


	/**
	 * Abre urlLink e baixa e retorna puro html sem qualquer filtragem
	 * 
	 * @param urlLink urlLink
	 * @return textoHtml textoHtml
	 */
	public String urlReader(String urlLink) {
		System.out.println("Inicio do UrlReader -> urlReader ");
		String textoHtml = new String();
		try {
			configProxy();
			URL url = new URL(urlLink);
			URLConnection uc = url.openConnection();
			BufferedReader in = new BufferedReader(
					new InputStreamReader(
							uc.getInputStream()));

			System.out.println("urlReader: ok ate aqui");
			// ler texto todo sem filtrar
			textoHtml = (new InFile()).getText(in);
			in.close();
		} catch (MalformedURLException e) {
			System.err.println(e.toString());
			System.exit(1);
		} catch (IOException e) {
			System.err.println(e);
			System.exit(1);
		}

		System.out.println("Fim do UrlReader -> urlReader ");
		return textoHtml;
	}


	/**
	 * urlPost
	 * @param urlLink urlLink
	 * @return textoHtml
	 */
	public String urlPost(String urlLink) {
		System.out.println("Inicio do UrlReader -> urlPost ");

		String textoHtml = new String();
		try {

			configProxy();
			URL url = new URL(urlLink);
			URLConnection uc = url.openConnection();
			uc.setDoOutput(true);
			uc.setDoInput(true);
			((HttpURLConnection) uc).setRequestMethod("POST");
			uc.setRequestProperty("Content-Type",
			"application/soap+xml; charset=\"utf-8\"");
			uc.setRequestProperty("Content-Length", "nnnn");
			Writer w = new OutputStreamWriter(uc.getOutputStream());

			// Envia pedido soap
			String xmlRequest = new InFile().readFile("ops_family.xml");
			w.write(xmlRequest);
			w.flush();
			w.close();

			// recebe a resposta
			BufferedReader in = new BufferedReader(new InputStreamReader(uc
					.getInputStream()));

			System.out.println("urlReader: ok ate aqui");

			// ler texto todo sem filtrar
			textoHtml = (new InFile()).getText(in);
			in.close();
		} catch (MalformedURLException e) {
			System.err.println(e.toString());
			System.exit(1);
		} catch (IOException e) {
			System.err.println(e);
			System.exit(1);
		}

		System.out.println("Fim do UrlReader -> urlPost ");
		return textoHtml;
	}

	/**
	 * Envia pedido de documento para o ops.espacenet.com em formato xml+soap e
	 * recebe a resposta
	 * 
	 * @param inputRequest inputRequest
	 * @return result resposta do pedido
	 * @throws Exception
	 */
	public String sendAndRetrieve(String inputRequest) throws Exception {
		System.out.println("Inicio do UrlReader -> sendAndRetrieve ");

		String result = "";
		// Configure proxy ...
		configProxy();

		// Set SOAP web service properties
		URL url = new URL(
		"http://ops.espacenet.com/OpenPatentServices/webService");
		SOAPMappingRegistry smr = new SOAPMappingRegistry();
		smr.mapTypes(Constants.NS_URI_SOAP_ENC, new QName("", "return"), null,
				null, new FloatDeserializer());

		// build the call
		// WSDLMEPClientBuilder call = new WSDLMEPClientBuilder(result);
		Call call = new Call();

		// prepare the registry of the call
		call.setSOAPMappingRegistry(smr);
		// the urn of the target service
		call.setTargetObjectURI("urn:EPO-OpenPatentServices");
		call.setMethodName("getPatentData");
		call.setEncodingStyleURI(Constants.NS_URI_LITERAL_XML);

		// Set parameters for input request (common part)
		// Set parameters for input request
		Vector<Parameter> params = new Vector<Parameter>();
		params.addElement((Parameter) new org.apache.soap.rpc.Parameter(
				"input_request", String.class, inputRequest,
				Constants.NS_URI_SOAP_ENC));
		call.setParams(params);
		org.apache.soap.rpc.Response resp;
		try {
			resp = call.invoke(url, "");
		} catch (SOAPException e) {
			System.out.println(e.getMessage());
			return (String) e.getMessage();
		}

		// If no error generated, convert response into String and return
		if (!resp.generatedFault()) {
			org.apache.soap.rpc.Parameter ret = resp.getReturnValue();
			result = (String) ret.getValue();
		}

		System.out.println("Fim do UrlReader -> sendAndRetrieve ");
		return result;
	}



	/**
	 * axisCall
	 * @param inputRequest
	 * @return result
	 * @throws Exception
	 */
	public String axisCall(String inputRequest) throws Exception {

		System.out.println("Inicio do UrlReader -> axisCall ");	

		String result = "";
		// Configure proxy ...
		configProxy();
		URL url = new URL("http://ops.espacenet.com/OpenPatentServices/webService");

		Call call = new Call();
		call.setTargetObjectURI("urn:EPO-OpenPatentServices");
		call.setMethodName("getPatentData");
		call.setEncodingStyleURI(Constants.NS_URI_LITERAL_XML);

		// Set parameters for input request
		Vector<Parameter> params = new Vector<Parameter>();
		params.addElement((Parameter) new org.apache.soap.rpc.Parameter(
				"input_request", String.class, inputRequest,
				Constants.NS_URI_SOAP_ENC));
		call.setParams(params);
		org.apache.soap.rpc.Response resp;
		try {
			resp = call.invoke(url, "");
		} catch (org.apache.soap.SOAPException e) {
			// gdcLog.warn("Error occured when generating SOAP response");
			return (String) e.getMessage();
		}
		// If no response generated, convert response into String and return
		if (!((org.apache.soap.rpc.Response) resp).generatedFault()) {
			org.apache.soap.rpc.Parameter ret = resp.getReturnValue();
			result = ret.getValue().toString();
		}

		System.out.println("Fim do UrlReader -> axisCall ");	
		return result;
	}



	/**
	 * urlImageWriter-- baixa e arquiva imagem PNG
	 * 
	 * @param urlLink urlLink
	 * @param filename filename
	 */
	public void urlImageWriter(String urlLink, String filename) {

		System.out.println("Inicio do UrlReader -> urlImageWriter ");	
		try {
			// Configure proxy ...
			configProxy();
			// Open URL ...
			URL url = new URL(urlLink);
			URLConnection uc = url.openConnection();
			InputStream in = uc.getInputStream();

			// l� toda a imagem png
			(new InFile()).getImage(in, filename);
			in.close();
		} catch (MalformedURLException e) {
			System.err.println(e.toString());
			System.exit(1);
		} catch (IOException e) {
			System.err.println(e);
			System.exit(1);
		}
		System.out.println("Fim do UrlReader -> urlImageWriter ");	
	}










	/////////////////////////////////////////////////////////////////
	/////////////////////////////////////////////////////////////////
	///////////// TENTAR UTILIZAR A NOVA LIB PRA WGET EM JAVA!!!!!////
	/////////////////////////////////////////////////////////////////
	/////////////////////////////////////////////////////////////////
	/**
	 *  Baixa dados da internet no linque urlLinks com o wget 
	 *  e cria um arquivo de saida chamado outFilename		
	 * @param urlLinks
	 * @param outFilename
	 */
	public void urlWgetReader(String urlLinks, String outFilename) {
		System.out.println("Inicio do UrlReader -> urlWgetReader ");	

		// Chame o wget para baixar paginas
		Runtime rt = Runtime.getRuntime();

		// String wgetCall = "wget --proxy=on
		// abatista:aab1Inpi@172.16.136.1:8080 "+urlLinks+" -O
		// C:\\\\cygwin\\\\home\\\\batista\\\\test.html";
		// String wgetCall = "./wget.sh";
		// String wgetCall = "wget --proxy=on
		// abatista:aab1Inpi@172.16.136.1:8080 "+urlLinks+" -nv -nd -";
		String wgetFile = "wget.sh";
		String wgetCall = "wget -o wget.log -O " + outFilename + " " + urlLinks;
		new PrintFile(wgetFile, wgetCall);
		// String wgetOutput = "";
		// Process proc;
		System.out.println(wgetCall);

		try {
			Process proc = rt.exec("./wget.sh");


			//VARIAVEL NUNCA LIDA ?????????????
			int rtnValue = proc.waitFor(); 
			//VARIAVEL NUNCA LIDA ?????????????

			// System.setIn(proc.getInputStream());
			// BufferedReader bf= new BufferedReader(
			// new InputStreamReader(proc.getInputStream()) );
			// String s;
			// while((s = bf.readLine())!= null){
			// wgetOutput+= s + "\n";
			// System.out.println(s);
			// }
			// bf.close();

		} catch (InterruptedException e) {
			System.err.println(e);
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}

		System.out.println("Fim do UrlReader -> urlWgetReader ");	

	}




	/**
	 * generic htmlFilter
	 * 
	 * @param text text
	 * @return cleanText cleanText
	 */
	public String htmlFilter(String text) {
		System.out.println("Inicio do UrlReader -> htmlFilter ");	

		text = text.replaceAll("<", "\n<");
		text = text.replaceAll(">", ">\n");
		text = text.replaceAll("&nbsp;", " ");
		String cleanText = new String();
		String[] textArray = text.split("\n");
		int isScript = 0;
		int isJunk = 0;
		for (int i = 0; i < textArray.length; i++) {
			if (textArray[i].matches("^$"))
				continue;// discard empty lines
			if (textArray[i].matches("^ +$"))
				continue;
			if (textArray[i].contains("<script")) {
				isScript = 1;
				System.out.println("isScript " + isScript + i);
				continue;
			}
			if (textArray[i].contains("</script>")) {
				isScript = 0;
				System.out.println("isScript " + isScript + i);
				continue;
			}
			if (textArray[i].contains("<style")) {
				isJunk = 1;
				continue;
			}
			if (textArray[i].contains("</style>")) {
				isJunk = 0;
				continue;
			}
			if (textArray[i].contains("<STYLE")) {
				isJunk = 1;
				continue;
			}
			if (textArray[i].contains("</STYLE>")) {
				isJunk = 0;
				continue;
			}
			if (textArray[i].contains("<!-- TABS START -->")) {
				isJunk = 1;
				continue;
			}
			if (textArray[i].contains("<!-- TABS END -->")) {
				isJunk = 0;
				continue;
			}
			if (isScript == 1 || isJunk == 1)
				continue;// elimina c�digo de scripts
			/*
			 * if (textArray[i].contains(">")) continue; // discard lines with >
			 * if (textArray[i].contains("}")) continue; if
			 * (textArray[i].contains("{")) continue;
			 */
			// System.out.println("i="+ i);
			cleanText = cleanText.concat("\n" + textArray[i]);
			System.out.println("textArray.length= " + textArray[i].length()
					+ " " + cleanText.length());

		}
		cleanText = cleanText.replaceAll("<.*?>", "");
		cleanText = cleanText.replaceAll("&gt;", ">");
		cleanText = cleanText.replaceAll("&lt;", "<");
		// substitua multiplas linhas vazias por uma so
		cleanText = cleanText.replaceAll(" *?\n *?\n", "\n");
		cleanText = cleanText.replaceAll("\n\n+", "\n");

		System.out.println("Fim do UrlReader -> htmlFilter ");	
		return cleanText;

	}

	/**
	 * @deprecated
	 * @param in
	 * @return
	 */
//	String htmlFilter(BufferedReader in) {
//	System.out.println("Inicio do UrlReader -> htmlFilter ");	
//	String cleanText = new String();
//	try {
//	String temp = new String();
//	String inputLine;
//	while ((inputLine = in.readLine()) != null) {
//	// inputLine=inputLine.replaceAll("<[^<>].+>"," ");
//	inputLine = inputLine.replaceAll(" +\n +", "\n");
//	inputLine = inputLine.replaceAll("<", "\n<");
//	inputLine = inputLine.replaceAll(">", ">\n");
//	temp = temp.concat(inputLine);
//	}

//	String[] textArray = temp.split("\n");
//	System.out.println("htmlReader: ok at� aqui " + temp.length());
//	int isScript = 0;
//	int isJunk = 0;
//	for (int i = 0; i < textArray.length; i++) {
//	if (textArray[i].matches("^$"))
//	continue;// discard empty lines
//	if (textArray[i].matches("^ +$"))
//	continue;
//	if (textArray[i].contains("<script")) {
//	isScript = 1;
//	System.out.println("isScript " + isScript + i);
//	continue;
//	}
//	if (textArray[i].contains("</script>")) {
//	isScript = 0;
//	System.out.println("isScript " + isScript + i);
//	continue;
//	}
//	if (textArray[i].contains("<style")) {
//	isJunk = 1;
//	continue;
//	}
//	if (textArray[i].contains("</style>")) {
//	isJunk = 0;
//	continue;
//	}
//	if (textArray[i].contains("<STYLE")) {
//	isJunk = 1;
//	continue;
//	}
//	if (textArray[i].contains("</STYLE>")) {
//	isJunk = 0;
//	continue;
//	}
//	if (textArray[i].contains("<!-- TABS START -->")) {
//	isJunk = 1;
//	continue;
//	}
//	if (textArray[i].contains("<!-- TABS END -->")) {
//	isJunk = 0;
//	continue;
//	}
//	if (isScript == 1 || isJunk == 1)
//	continue;// elimina c�digo de scripts
//	if (textArray[i].contains(">"))
//	continue; // discard lines with >
//	if (textArray[i].contains("}"))
//	continue;
//	if (textArray[i].contains("{"))
//	continue;
//	// System.out.println("i="+ i);
//	cleanText = cleanText.concat("\n" + textArray[i]);
//	System.out.println("textArray.length= " + textArray[i].length()
//	+ " " + cleanText.length());

//	}
//	} catch (IOException e) {
//	System.err.println(e);
//	System.exit(1);
//	}
//	cleanText = cleanText.replaceAll("&nbsp;", " ");
//	cleanText = cleanText.replaceAll("&gt;", ">");
//	cleanText = cleanText.replaceAll("&lt;", "<");

//	System.out.println("Fim do UrlReader -> htmlFilter ");	
//	return cleanText;
//	}








	/**
	 * US patent filter
	 * patReader
	 * @param in in
	 */
	void patReader(BufferedReader in) {

		System.out.println("Inicio do UrlReader -> patReader ");	
		String inputLine;
		try {
			while ((inputLine = in.readLine()) != null) {
				if (inputLine.contains("<font")) {
					title = inputLine.replace("<font size=\"+1\">", "");
					title = title.replace("</font>", "");
					title = title.replace("<BR>", "");
				}
				if (inputLine.contains("Abstract")) {
					while (!inputLine.contains("</P>")) {
						inputLine = htmlCleanUp(inputLine);
						absTract = absTract.concat(inputLine);
						inputLine = in.readLine();
					}
				}
				if (inputLine.contains("Claims")) {
					while (inputLine.contains("Description") == false) {
						inputLine = htmlCleanUp(inputLine);
						claims = claims.concat(inputLine);
						inputLine = in.readLine();
					}
				}
				if (inputLine.contains("Description")) {
					while (inputLine.contains("http") == false) {
						inputLine = htmlCleanUp(inputLine);
						description = description.concat(inputLine);
						inputLine = in.readLine();
					}
				}
			}
		} catch (IOException e) {
			System.err.println(e);
			System.exit(1);
		}

		System.out.println("Fim do UrlReader -> patReader ");	
	}




	/**
	 * htmlCleanUp -- cleans html source to be deprecated
	 * 
	 * @param s
	 * @return s
	 */
	public String htmlCleanUp(String s) {
		System.out.println("Inicio do UrlReader -> htmlCleanUp ");	
		s = s.replaceAll("<[a-zA-Z0-9]*?>", "\n");
		s = s.replaceAll("</CENTER>", "\n");
		s = s.replaceAll("</[BIP]>", "");
		System.out.println("Fim do UrlReader -> htmlCleanUp ");	
		return s;
	}



	/**
	 * getTitle
	 * @return title
	 */
	public String getTitle() {
		return title;
	}


	/**
	 * setTitle
	 * @param title title
	 */
	public void setTitle(String title) {
		this.title = title;
	}


	/**
	 * getAbsTract
	 * @return absTract
	 */
	public String getAbsTract() {
		return absTract;
	}


	/**
	 * setAbsTract
	 * @param absTract absTract
	 */
	public void setAbsTract(String absTract) {
		this.absTract = absTract;
	}


	/**
	 * getClaims
	 * @return claims
	 */
	public String getClaims() {
		return claims;
	}


	/**
	 * setClaims
	 * @param claims claims
	 */
	public void setClaims(String claims) {
		this.claims = claims;
	}


	/**
	 * getDescription
	 * @return description
	 */
	public String getDescription() {
		return description;
	}


	/**
	 * setDescription
	 * @param description description
	 */
	public void setDescription(String description) {
		this.description = description;
	}


}
